package org.opencare.plugins.gdacs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class RSSPoller implements ResourcePoller {

	/** Logger for this class and subclasses */
	protected final Log logger = LogFactory.getLog(getClass());
	private String memLastModified = null;
	private String memETag = null;

	public String getMemETag() {
		return memETag;
	}

	public void setMemETag(String memETag) {
		this.memETag = memETag;
	}

	public String getMemLastModified() {
		return memLastModified;
	}

	public void setMemLastModified(String memLastModified) {
		this.memLastModified = memLastModified;
	}

	public String getResource(String target) {
		// TODO Auto-generated method stub

		logger.info("Polling resource from: " + target);

		URL sourceURL;
		StringBuffer lineBuf = new StringBuffer();

		try {
			sourceURL = new URL(target);

			// obtain the connection
			HttpURLConnection sourceConnection = (HttpURLConnection) sourceURL
					.openConnection();
			// add parameters to the connection
			HttpURLConnection.setFollowRedirects(true);
			
			// allow both GZip and Deflate (ZLib) encodings
			sourceConnection.setRequestProperty("Accept-Encoding",
					"gzip, deflate");

			// obtain the ETag from a local store, returns null if not found
			String etag = getMemETag();
			logger.info("ETag: " + etag);

			if (etag != null) {
				sourceConnection.addRequestProperty("If-None-Match", etag);
			}

			// obtain the Last-Modified from a local store, returns null if not
			// found
			String lastModified = getMemLastModified();
			logger.info("Last Modified: " + lastModified);

			if (lastModified != null) {
				sourceConnection.addRequestProperty("If-Modified-Since",
						lastModified);
			}

			// establish connection, get response headers
			sourceConnection.connect();

			// obtain the encoding returned by the server
			String encoding = sourceConnection.getContentEncoding();

			// if it returns Not modified then we already have the content,
			// return
			if (sourceConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
				// disconnect() should only be used when you won't
				// connect to the same site in a while,
				// since it disconnects the socket. Only losing
				// the stream on an HTTP 1.1 connection will
				// maintain the connection waiting and be
				// faster the next time around
				logger.info("------------ HTTP_NOT_MODIFIED ------------");
				logger.info("Then rss is not loadded!");
				sourceConnection.disconnect();
				return null;
			}

			// get the last modified & etag and
			// store them for the next check

			setMemLastModified(sourceConnection.getHeaderField("Last-Modified"));
			setMemETag(sourceConnection.getHeaderField("ETag"));

			InputStream resultingInputStream = null;

			// create the appropriate stream wrapper based on
			// the encoding type
			if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
				resultingInputStream = new GZIPInputStream(sourceConnection
						.getInputStream());
			} else if (encoding != null && encoding.equalsIgnoreCase("deflate")) {
				resultingInputStream = new InflaterInputStream(sourceConnection
						.getInputStream(), new Inflater(true));
			} else {
				resultingInputStream = sourceConnection.getInputStream();
			}

			InputStreamReader inR = new InputStreamReader(resultingInputStream);
			BufferedReader buf = new BufferedReader(inR);

			String line;
			while ((line = buf.readLine()) != null) {				
				lineBuf.append(line);
				lineBuf.append("\n");
			}

		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return lineBuf.toString();
	}

}
